<?php


namespace app\xiangji\services;


use app\common\models\Share;
use app\xiangji\exception\ServiceUnavailableException;
use Carbon\Carbon;
use EasyWeChat\Factory;
use EasyWeChat\Kernel\Http\StreamResponse;
use think\File;

class WechatService
{

    public $miniProgram;

    public function __construct()
    {
        // 获取小程序工厂实例
        $this->miniProgram = Factory::miniProgram(config('wechat.mini_program'));
    }

    /**
     * @todo    解密获取微信用户数据
     * @param string $code  登录凭证
     * @param string $iv    解密偏移量
     * @param string $encryptedData 加密数据
     * @return array
     * @throws \EasyWeChat\Kernel\Exceptions\DecryptException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     */
    public function decryptUserInfo(string $code, string $iv, string $encryptedData): array
    {
        //  根据 jsCode 获取用户 session 信息
        $session = $this->miniProgram->auth->session($code);
        //  获取电话等功能，信息是加密的，需要解密。
        return $this->miniProgram->encryptor->decryptData($session['session_key'], $iv, $encryptedData);
    }

    /**
     * @todo    解密获取微信用户手机号
     * @param string $code  登录凭证
     * @param string $iv    解密偏移量
     * @param string $encryptedData 加密数据
     * @return array
     * @throws \EasyWeChat\Kernel\Exceptions\DecryptException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidConfigException
     */
    public function decryptUserPhone(string $code, string $iv, string $encryptedData)
    {
        //  根据 jsCode 获取用户 session 信息
        $session = $this->miniProgram->auth->session($code);
        //  获取电话等功能，信息是加密的，需要解密。
        return $this->miniProgram->encryptor->decryptData($session['session_key'], $iv, $encryptedData);
    }

    /**
     * @todo 生成小程序
     * @param string $path  进入路径
     * @param $data         携带参数
     * @param int $width    宽度
     * @return array
     * @throws ServiceUnavailableException
     * @throws \EasyWeChat\Kernel\Exceptions\InvalidArgumentException
     * @throws \EasyWeChat\Kernel\Exceptions\RuntimeException
     */
    public function generateShareQRCode(string $path = 'pages/Home/home', $data, int $width = 430)
    {
        //  生成token，用于扫码解析数据
        $token = md5(Carbon::now()->getPreciseTimestamp(3) . mt_rand(10000, 99999));
        if ($data){
            // 如果有数据，则把数据和token一期保存到数据库
            Share::create(['token' => $token, 'data'  => $data]);
        }
        // 请求微信生成小程序码接口
        $response = $this->miniProgram->app_code->getUnlimit($token, [
            'path'  => $path,
            'width' => $width
        ]);
        if ($response instanceof StreamResponse){
            // 保存小程序码到本地文件系统
            $filename = 'love_time_qr_' . Carbon::now()->getPreciseTimestamp(3) . mt_rand(10000, 99999) . '.png';
            $local_path = '/tmp/qrcode';
            $response->saveAs($local_path, $filename);
            // 上传到Oss
            $result = (new FileService())->uploadShareCode(new File($local_path . '/' . $filename));
            // 上传后删除本地文件
            unlink($local_path . '/' . $filename);
            return $result;
        }
        throw new ServiceUnavailableException('系统错误，请稍后再试');
    }

    public function checkText(string $content)
    {
        return $this->miniProgram->content_security->checkText($content);
    }

    public function checkImage(string $path)
    {
        return $this->miniProgram->content_security->checkImage($path);
    }
}
